using System;
using System.Collections.Generic;
using System.Text;
using Zsa.Emulation.Cartridge;

namespace Zsa.Emulation.Mappers
{
    public static class MapperFactory
    {
        #region Fields
        /// <summary>
        /// Dictionary of mapper names and their handles.
        /// </summary>
        private static Dictionary<MapperTypeNumber, MapperInformation> _Mappers =
            new Dictionary<MapperTypeNumber, MapperInformation>(20);
        #endregion Fields

        #region Constructor
        /// <summary>
        /// Initializes the <see cref="T:MapperFactory"/> class.
        /// </summary>
        static MapperFactory()
        {
            try
            {
                Init();
            }
            finally
            {
            }
        }
        #endregion Constructor

        #region Methods
        /// <summary>
        /// Inits this instance.
        /// </summary>
        public static void Init()
        {
            _Mappers.Add(MapperTypeNumber.None, new MapperInformation("None", "No Mapper", typeof(Mappers.DefaultMapper),
                MapperTypeNumber.None));
            _Mappers.Add(MapperTypeNumber.UNROM, new MapperInformation("UNROM", "UNROM", typeof(Mappers.UnromMapper),
                MapperTypeNumber.UNROM));
            _Mappers.Add(MapperTypeNumber.CNROM, new MapperInformation("CNROM", "CNROM", typeof(Mappers.UnromMapper),
                MapperTypeNumber.CNROM));
        }

        /// <summary>
        /// Creates the mapper.
        /// </summary>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
        public static Mapper CreateMapper(CartridgeFileInfo fileInfo)
        {
            return CreateMapper(fileInfo.MapperInformation);
        }

        /// <summary>
        /// Creates the mapper.
        /// </summary>
        /// <param name="mapperInfo">The mapper info.</param>
        /// <returns></returns>
        public static Mapper CreateMapper(MapperInformation mapperInfo)
        {
            if (mapperInfo.IsEmpty || mapperInfo.IsUnsupported)
            {
                throw new Mappers.UnknownMapperException();
            }

            //if (mapperInfo.IsStandardMapper)
            //{
            //    return GetMapperInfo(mapperInfo.MapperTypeNumber);
            //}
            return Activator.CreateInstance(mapperInfo.MapperType,new object[0]) as Mapper;
        }



        /// <summary>
        /// Gets the mapper info.
        /// </summary>
        /// <param name="mapperType">Type of the mapper.</param>
        /// <returns></returns>
        internal static MapperInformation GetMapperInfo(MapperTypeNumber mapperType)
        {
            MapperInformation _MapperInfo;
            if (!_Mappers.TryGetValue(mapperType, out _MapperInfo))
            {
                string _MapperName;
                if (Enum.IsDefined(typeof(MapperTypeNumber), mapperType))
                {
                    _MapperName = mapperType.ToString();
                }
                else
                {
                    _MapperName = "Unknown";
                }
                return new MapperInformation(_MapperName, "Unsupported Mapper", null,
                    mapperType | Mappers.MapperTypeNumber.Unsupported);
            }
            return _MapperInfo;
        }

        #endregion Methods
    }
}
